home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PsL Monthly 1993 December
/
PSL Monthly Shareware CD-ROM (December 1993).iso
/
prgmming
/
dos
/
c
/
newmat.exe
/
EXAMPLE.CXX
< prev
next >
Wrap
C/C++ Source or Header
|
1991-07-30
|
7KB
|
178 lines
//$$ example.cxx Example of use of matrix package
typedef double real; // all floating point double
#include "include.hxx" // include standard files
#include "newmatap.hxx" // need matrix applications
real t3(real); // round to 3 decimal places
// demonstration of matrix package on linear regression problem
main()
{
// the data
// you may need to read this data using cin if you are using a
// compiler that doesn't understand aggregates
real y[] = { 8.3, 5.5, 8.0, 8.5, 5.7, 4.4, 6.3, 7.9, 9.1 };
real x1[] = { 2.4, 1.8, 2.4, 3.0, 2.0, 1.2, 2.0, 2.7, 3.6 };
real x2[] = { 1.7, 0.9, 1.6, 1.9, 0.5, 0.6, 1.1, 1.0, 0.5 };
for (i=0; i<9;i++) cin >> y[i];
for (i=0; i<9;i++) cin >> x1[i];
for (i=0; i<9;i++) cin >> x2[i];
int nobs = 9; // number of observations
int npred = 2; // number of predictor values
int npred1 = npred+1;
// we want to find the values of a,a1,a2 to give the best
// fit of y[i] with a0 + a1*x1[i] + a2*x2[i]
// this example demonstrates three methods of calculation
{
// traditional sum of squares and products method of calculation
// with subtraction of means
// make matrix of predictor values
Matrix X(nobs,npred);
// load x1 and x2 into X
// [use << rather than = with submatrices and/or loading arrays]
X.Col(1) << x1; X.Col(2) << x2;
// vector of Y values
ColumnVector Y(nobs); Y << y;
// make vector of 1s
ColumnVector Ones(nobs); Ones = 1.0;
// calculate means (averages) of x1 and x2 [ .t() takes transpose]
RowVector M = Ones.t() * X / nobs;
// and subtract means from x1 and x1
Matrix XC(nobs,npred);
XC = X - Ones * M;
// do the same to Y [need (1,1) to convert 1x1 matrix to scalar]
ColumnVector YC(nobs);
real m = Matrix(Ones.t() * Y)(1,1) / nobs; YC = Y - Ones * m;
// form sum of squares and product matrix
// [use << rather than = for copying Matrix into SymmetricMatrix]
SymmetricMatrix SSQ; SSQ << XC.t() * XC;
// calculate estimate
// [bracket last two terms to force this multiplication first]
// [ .i() means inverse, but inverse is not explicity calculated]
ColumnVector A = SSQ.i() * (XC.t() * YC);
// calculate estimate of constant term
real a = m - Matrix(M * A)(1,1);
// Get variances of estimates from diagonal elements of invoice of SSQ
// [ we are taking inverse of SSQ; would have been better to use
// CroutMatrix method - see documentation ]
Matrix ISSQ = SSQ.i(); DiagonalMatrix D; D << ISSQ;
ColumnVector V = D.CopyToColumn();
real v = 1.0/nobs + Matrix(M * ISSQ * M.t())(1,1);
// for calc variance const
// Calculate fitted values and residuals
ColumnVector Fitted = X * A + a;
ColumnVector Residual = Y - Fitted;
real ResVar = Residual.SumSquare() / (nobs-npred1);
// print out answers
cout << "\nEstimates and their standard errors\n\n";
cout << a <<"\t"<< sqrt(v*ResVar) << "\n";
for (int i=1; i<=npred; i++)
cout << A(i) <<"\t"<< sqrt(V(i)*ResVar) << "\n";
cout << "\nObservations, fitted value, residual value\n";
for (i=1; i<=nobs; i++)
cout << X(i,1) <<"\t"<< X(i,2) <<"\t"<< Y(i) <<"\t"<<
t3(Fitted(i)) <<"\t"<< t3(Residual(i)) <<"\n";
cout << "\n\n";
}
{
// traditional sum of squares and products method of calculation
// with subtraction of means - using Cholesky decomposition
Matrix X(nobs,npred);
X.Col(1) << x1; X.Col(2) << x2;
ColumnVector Y(nobs); Y << y;
ColumnVector Ones(nobs); Ones = 1.0;
RowVector M = Ones.t() * X / nobs;
Matrix XC(nobs,npred);
XC = X - Ones * M;
ColumnVector YC(nobs);
real m = Matrix(Ones.t() * Y)(1,1) / nobs; YC = Y - Ones * m;
SymmetricMatrix SSQ; SSQ << XC.t() * XC;
// Cholesky decomposition of SSQ
LowerTriangularMatrix L = Cholesky(SSQ);
// calculate estimate
ColumnVector A = L.t().i() * (L.i() * (XC.t() * YC));
// calculate estimate of constant term
real a = m - Matrix(M * A)(1,1);
// Get variances of estimates from diagonal elements of invoice of SSQ
DiagonalMatrix D; D << L.t().i() * L.i();
ColumnVector V = D.CopyToColumn();
real v = 1.0/nobs + (L.i() * M.t()).SumSquare();
// Calculate fitted values and residuals
ColumnVector Fitted = X * A + a;
ColumnVector Residual = Y - Fitted;
real ResVar = Residual.SumSquare() / (nobs-npred1);
// print out answers
cout << "\nEstimates and their standard errors\n\n";
cout << a <<"\t"<< sqrt(v*ResVar) << "\n";
for (int i=1; i<=npred; i++)
cout << A(i) <<"\t"<< sqrt(V(i)*ResVar) << "\n";
cout << "\nObservations, fitted value, residual value\n";
for (i=1; i<=nobs; i++)
cout << X(i,1) <<"\t"<< X(i,2) <<"\t"<< Y(i) <<"\t"<<
t3(Fitted(i)) <<"\t"<< t3(Residual(i)) <<"\n";
cout << "\n\n";
}
{
// Householder triangularisation method
// load data - 1s into col 1 of matrix
Matrix X(nobs,npred1); ColumnVector Y(nobs);
X.Col(1) << 1.0; X.Col(2) << x1; X.Col(3) << x2; Y << y;
// do Householder triangularisation
// no need to deal with constant term separately
Matrix XT = X.t(); // Want data to be along rows
RowVector YT = Y.t();
LowerTriangularMatrix L; RowVector M;
HHDecompose(XT, L); HHDecompose(XT, YT, M); // YT now contains resids
ColumnVector A = L.t().i() * M.t();
ColumnVector Fitted = X * A;
real ResVar = YT.SumSquare() / (nobs-npred1);
// get variances of estimates
L << L.i();
DiagonalMatrix D; D << L.t() * L;
// print out answers
cout << "\nEstimates and their standard errors\n\n";
for (int i=1; i<=npred1; i++)
cout << A(i) <<"\t"<< sqrt(D(i)*ResVar) << "\n";
cout << "\nObservations, fitted value, residual value\n";
for (i=1; i<=nobs; i++)
cout << X(i,2) <<"\t"<< X(i,3) <<"\t"<< Y(i) <<"\t"<<
t3(Fitted(i)) <<"\t"<< t3(YT(i)) <<"\n";
cout << "\n\n";
}
}
real t3(real r) { return int(r*1000) / 1000.0; }